package com.yingxin.yxerp.module.activiti.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.yingxin.yx.framework.commons.activiti.def.ApprovalFormMeta;
import com.yingxin.yx.framework.commons.activiti.def.ConditionExpression;
import com.yingxin.yx.framework.commons.activiti.def.ConditionMeta;
import com.yingxin.yx.framework.commons.activiti.def.TaskDef;
import com.yingxin.yx.framework.commons.activiti.enums.AssigneeType;
import com.yingxin.yx.framework.commons.activiti.enums.ConditionType;
import com.yingxin.yx.framework.commons.activiti.enums.FormKey;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.commons.exception.BizException;
import com.yingxin.yx.framework.commons.helper.ListHelper;
import com.yingxin.yxerp.module.activiti.entity.ActivitiForm;
import com.yingxin.yxerp.module.activiti.entity.ActivitiFormBpmn;
import com.yingxin.yxerp.module.oplog.aop.OplogAnnotation;
import com.yingxin.yxerp.module.organization.entity.Department;
import com.yingxin.yxerp.module.organization.entity.User;
import com.yingxin.yxerp.module.organization.service.IDepartmentService;
import com.yingxin.yxerp.module.organization.service.IUserService;
import com.yingxin.yxerp.module.print.constant.PrintLimitTypeConst;
import com.yingxin.yxerp.module.print.entity.PrintLimit;
import com.yingxin.yxerp.module.print.service.IPrintLimitService;
import com.yingxin.yxerp.module.sys.entity.constants.PatternConstants;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.util.io.BytesStreamSource;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.validation.ProcessValidator;
import org.activiti.validation.ProcessValidatorFactory;
import org.activiti.validation.ValidationError;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class ActivitiProcessDeployService {

    private final Logger logger = LoggerFactory.getLogger(ActivitiProcessDeployService.class);

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IPrintLimitService printLimitService;

    @Autowired
    private IActivitiFormBpmnService activitiFormBpmnService;

    /**
     * 部署流程
     */
    @OplogAnnotation(biz = BusinessType.AUDIT_PROCESS, id = "{{activitiForm.id}}", action = "编辑", desc = "流程[{{activitiForm.name}}]")
    @Transactional(rollbackFor = RuntimeException.class)
    public void deploy(ActivitiForm activitiForm, String bpmnContent, String bpmnGraphData, List<TaskDef> tasks,
                       List<ConditionExpression> conditionExpressions) {
        logger.info("==========>bpmnContent : " + bpmnContent);
        if (activitiForm == null) {
            throw new BizException("表单不存在");
        }
        if (bpmnContent == null) {
            throw new BizException("流程为空");
        }
        // 前端反馈对xml非法字符无能为力，所以后端全局替换
        bpmnContent = disposeIllegalCharacter(bpmnContent);
        // xml 转 BpmnModel
        BytesStreamSource bytesStreamSource = new BytesStreamSource(bpmnContent.getBytes());
        BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
        BpmnModel bpmnModel = bpmnXMLConverter.convertToBpmnModel(bytesStreamSource,
                false, false, "UTF-8");
        // 只能有一个 Process
        List<Process> processList = bpmnModel.getProcesses();
        if (processList.size() > 1) {
            throw new BizException("流程异常");
        }
        Process process = processList.get(0);
        process.setExecutable(true);
        process.setId(activitiForm.getId());
        // 验证流程逻辑
        validProcessLogic(process);
        // 处理xml用户任务
        handleUserTaskElement(process, tasks, activitiForm);
        // 处理xml流程条件
        handleSequenceFlowElement(activitiForm, process, conditionExpressions);
        // 清除xml上一些奇怪的东西 cleanAttributes
        cleanAttributes(process);
        // 验证 BpmnModel
        ProcessValidatorFactory processValidatorFactory = new ProcessValidatorFactory();
        ProcessValidator defaultProcessValidator = processValidatorFactory.createDefaultProcessValidator();
        List<ValidationError> validate = defaultProcessValidator.validate(bpmnModel);
        if (validate.size() > 0) {
            throw new BizException(validate.get(0).getProblem());
        }
        // resourceName
        String resourceName = activitiForm.getId() + ".bpmn";
        // 进行部署
        byte[] bytes = bpmnXMLConverter.convertToXML(bpmnModel, "UTF-8");
        logger.info("==========>bpmn string : " + new String(bytes, StandardCharsets.UTF_8));
        Deployment deployment = repositoryService.createDeployment()
                //.addBpmnModel(resourceName, bpmnModel)
                .addBytes(resourceName, bytes)
                .name(activitiForm.getName())
                .key(activitiForm.getId())
                .deploy();
        // deployment = repositoryService.createDeploymentQuery().deploymentId(deployment.getId()).singleResult();
        // 查询流程定义对象
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();
        if (processDefinition == null) {
            throw new BizException("部署失败");
        }
        // 更新表单
        ActivitiFormBpmn activitiFormBpmn = new ActivitiFormBpmn();
        activitiFormBpmn.setId(activitiForm.getId());
        activitiFormBpmn.setProcessDefinitionId(processDefinition.getId());
        activitiFormBpmn.setProcessVersion(String.valueOf(processDefinition.getVersion()));
        activitiFormBpmn.setBpmnContent(bpmnContent);
        activitiFormBpmn.setBpmnTask(JSON.toJSONString(tasks));
        activitiFormBpmn.setBpmnConditionExpression(JSON.toJSONString(conditionExpressions));
        activitiFormBpmn.setBpmnGraphData(bpmnGraphData);
        activitiFormBpmn.setUpdateTime(new Date());
        activitiFormBpmnService.saveOrUpdate(activitiFormBpmn);
    }


    /**
     * 前端反馈对xml非法字符无能为力，所以后端全局替换
     */
    private String disposeIllegalCharacter(String bpmnContent) {
        // bpmnContent 是前端生成的xml内容
        bpmnContent = bpmnContent.replaceAll("<\\bactions\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcandidateUsers\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bccType\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcc\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bgroups\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bccGroup\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bactionDefList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcarbonCopyList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionDeptIdList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionPersonIdList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionLineIdList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcompanyIdList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bsaleTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bbusinessTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bbruiseTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bsdtList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\breimbursementTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\breplacePersonIdList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bworkInjuryTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcategory\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\btransferTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bfundTypeList\\s+[\\w+=\"\\w+\"\\s+]*/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bisInMyCompany\\s+[\\w+=\"\\w+\"\\s+]*/>", "");

        bpmnContent = bpmnContent.replaceAll("<\\bactions\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcandidateUsers\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bccType\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcc\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bgroups\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bccGroup\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bactionDefList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcarbonCopyList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionDeptIdList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionPersonIdList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bconditionLineIdList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcompanyIdList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bsaleTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bbusinessTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bbruiseTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bsdtList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\breimbursementTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\breplacePersonIdList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bworkInjuryTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bcategory\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\btransferTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bfundTypeList\\s+/>", "");
        bpmnContent = bpmnContent.replaceAll("<\\bisInMyCompany\\s+/>", "");

        bpmnContent = bpmnContent.replaceAll("<actions>[\\s*\\S*]*</actions>", "");
        bpmnContent = bpmnContent.replaceAll("<candidateUsers>[\\s*\\S*]*</candidateUsers>", "");
        bpmnContent = bpmnContent.replaceAll("<ccType>[\\s*\\S*]*</ccType>", "");
        bpmnContent = bpmnContent.replaceAll("<cc>[\\s*\\S*]*</cc>", "");
        bpmnContent = bpmnContent.replaceAll("<groups>[\\s*\\S*]*</groups>", "");
        bpmnContent = bpmnContent.replaceAll("<ccGroup>[\\s*\\S*]*</ccGroup>", "");
        bpmnContent = bpmnContent.replaceAll("<actionDefList>[\\s*\\S*]*</actionDefList>", "");
        bpmnContent = bpmnContent.replaceAll("<carbonCopyList>[\\s*\\S*]*</carbonCopyList>", "");
        bpmnContent = bpmnContent.replaceAll("<conditionDeptIdList>[\\s*\\S*]*</conditionDeptIdList>", "");
        bpmnContent = bpmnContent.replaceAll("<conditionPersonIdList>[\\s*\\S*]*</conditionPersonIdList>", "");
        bpmnContent = bpmnContent.replaceAll("<conditionLineIdList>[\\s*\\S*]*</conditionLineIdList>", "");
        bpmnContent = bpmnContent.replaceAll("<companyIdList>[\\s*\\S*]*</companyIdList>", "");
        bpmnContent = bpmnContent.replaceAll("<saleTypeList>[\\s*\\S*]*</saleTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<businessTypeList>[\\s*\\S*]*</businessTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<bruiseTypeList>[\\s*\\S*]*</bruiseTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<sdtList>[\\s*\\S*]*</sdtList>", "");
        bpmnContent = bpmnContent.replaceAll("<reimbursementTypeList>[\\s*\\S*]*</reimbursementTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<replacePersonIdList>[\\s*\\S*]*</replacePersonIdList>", "");
        bpmnContent = bpmnContent.replaceAll("<workInjuryTypeList>[\\s*\\S*]*</workInjuryTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<category>[\\s*\\S*]*</category>", "");
        bpmnContent = bpmnContent.replaceAll("<transferTypeList>[\\s*\\S*]*</transferTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<fundTypeList>[\\s*\\S*]*</fundTypeList>", "");
        bpmnContent = bpmnContent.replaceAll("<isInMyCompany>[\\s*\\S*]*</isInMyCompany>", "");

        return bpmnContent;
    }


    /**
     * 验证逻辑
     */
    private void validProcessLogic(Process process) {
        List<StartEvent> startEventList = new ArrayList<>();
        List<EndEvent> endEventList = new ArrayList<>();
        List<UserTask> userTaskList = new ArrayList<>();
        Collection<FlowElement> flowElements = process.getFlowElements();
        for (FlowElement element : flowElements) {
            if (element instanceof StartEvent) {
                startEventList.add((StartEvent) element);
            } else if (element instanceof EndEvent) {
                endEventList.add((EndEvent) element);
            } else if (element instanceof UserTask) {
                userTaskList.add((UserTask) element);
            }
        }
        // 开始 startEvent
        if (startEventList.size() != 1) {
            throw new BizException("错误，只能有一个开始节点");
        }
        StartEvent startEvent = startEventList.get(0);
        if (startEvent.getIncomingFlows().size() != 0) {
            throw new BizException("错误，开始节点不能有入口连线");
        }
        if (startEvent.getOutgoingFlows().size() == 0) {
            throw new BizException("错误，开始节点至少有一个出口连线");
        }
        // 结束 endEvent
        if (endEventList.size() == 0) {
            throw new BizException("错误，至少有一个结束节点");
        }
        for (EndEvent endEvent : endEventList) {
            if (endEvent.getIncomingFlows().size() == 0) {
                throw new BizException(" 错误，结束节点至少有一个入口连线");
            }
            if (endEvent.getOutgoingFlows().size() != 0) {
                throw new BizException(" 错误，结束节点不能有出口连线");
            }
        }
        // 任务 userTask
        if (userTaskList.size() == 0) {
            throw new BizException("错误，流程节点数量不能为0");
        }
        for (UserTask userTask : userTaskList) {
            if (userTask.getIncomingFlows().size() == 0) {
                throw new BizException(userTask.getName() + " 错误，流程节点至少有一个入口连线");
            }
            if (userTask.getOutgoingFlows().size() == 0) {
                throw new BizException(userTask.getName() + " 错误，流程节点至少有一个出口连线");
            }
        }
    }

    /**
     * 处理xml用户任务
     */
    private void handleUserTaskElement(Process process, List<TaskDef> tasks, ActivitiForm activitiForm) {
        List<ApprovalFormMeta> approvalFormMetaList = JSON.parseArray(activitiForm.getApprovalFormMetaContent(), ApprovalFormMeta.class);
        Map<String, ApprovalFormMeta> approvalFormMetaMap = ListHelper.toMap(ApprovalFormMeta::getFormKey, approvalFormMetaList);
        Map<String, TaskDef> tasksMap = ListHelper.toMap(TaskDef::getElementId, tasks);
        // 检查formkey的设置：除了[审核后打印]这个表单可以不用设置，其他表单必须设置
        // 财务审核表单只能设置一个
        int countDeduct = 0;
        for (String elementId : tasksMap.keySet()) {
            FlowElement flowElement = process.getFlowElement(elementId);
            if (flowElement == null) {
                throw new BizException("没有找到对应的 userTask");
            }
            UserTask userTask = (UserTask) flowElement;
            TaskDef taskDef = tasksMap.get(elementId);
            if (CollectionUtil.isEmpty(taskDef.getActionDefList()) || CollectionUtil.isEmpty(taskDef.getActions())) {
                throw new BizException(userTask.getName() + "，操作按钮设置异常");
            }
            if (StringUtils.isEmpty(taskDef.getFormKey())) {
                taskDef.setFormKey(FormKey.COMMON.getKey());
            }
            // 设置formKey
            userTask.setFormKey(taskDef.getFormKey());
            // 审核后打印 -> PRINT_LIMIT
            if (FormKey.PRINT_LIMIT.getKey().equals(taskDef.getFormKey())) {
                printLimitService.saveOrUpdate(new PrintLimit(activitiForm.getId(), PrintLimitTypeConst.LIMIT_1));
            }

            if ("deduct".equals(taskDef.getFormKey())) {
                countDeduct++;
            }
            approvalFormMetaMap.remove(taskDef.getFormKey());
        }
        if (countDeduct > 1) {
            throw new BizException("财务审核表单只能设置一个");
        }
        // 检查未设置表单
        if (approvalFormMetaMap.size() > 0) {
            for (String key : approvalFormMetaMap.keySet()) {
                if (!FormKey.PRINT_LIMIT.getKey().equals(key)) {
                    throw new BizException(approvalFormMetaMap.get(key).getName() + "表单未设置");
                }
            }
        }
        // 检查审批人
        for (String elementId : tasksMap.keySet()) {
            FlowElement flowElement = process.getFlowElement(elementId);
            if (flowElement == null) {
                throw new BizException("没有找到对应的 userTask");
            }
            TaskDef taskDef = tasksMap.get(elementId);
            UserTask userTask = (UserTask) flowElement;

            AssigneeType assigneeType = AssigneeType.getEnum(taskDef.getAssigneeType());
            if (assigneeType == null) {
                throw new BizException("审核人类型异常");
            }
            switch (assigneeType) {
                case USER:
                    if (StringUtils.isEmpty(taskDef.getAssignee())) {
                        throw new BizException("审核人不能为空");
                    }
                    User user = userService.getById(taskDef.getAssignee());
                    if (user == null) {
                        throw new BizException("提交的审核人异常,请检查该审核人");
                    }
                    userTask.setAssignee(taskDef.getAssignee());
                    break;
                case CANDIDATE_USERS:
                    if (CollectionUtil.isEmpty(taskDef.getCandidateUsers())) {
                        throw new BizException("审核人不能为空");
                    }
                    Set<String> candidateUsersSet = new HashSet<>();
                    for (String uid : taskDef.getCandidateUsers()) {
                        if (userService.getById(uid) == null) {
                            throw new BizException("提交的审核人异常,请检查该审核人");
                        }
                        candidateUsersSet.add(uid);
                    }
                    if (!CollectionUtil.isEmpty(taskDef.getReplacePersonIdList())){
                        for (String personId : taskDef.getReplacePersonIdList()) {
                            if (!candidateUsersSet.contains(personId)){
                                throw new BizException("审核人不包含代办人");
                            }
                        }
                    }

                    userTask.setCandidateUsers(new ArrayList<>(candidateUsersSet));
                    break;
                case DEPT_MGR:
                    if (StringUtils.isEmpty(taskDef.getDeptId())) {
                        throw new BizException("指定部门不能为空");
                    }
                    userTask.setAssignee("deptMgr_" + taskDef.getDeptId());
                    break;
                case GROUPS:
                    if (CollectionUtil.isEmpty(taskDef.getGroups())) {
                        throw new BizException("审核组不能为空");
                    }
                    Set<String> groupsSet = new HashSet<>(taskDef.getGroups());
                    userTask.setCandidateGroups(new ArrayList<>(groupsSet));
                    break;
                case APPLICANT:
                    userTask.setAssignee("${applicant}");
                    break;
                case APPLICANT_MGR:
                    userTask.setAssignee("applicantMgr");
                    break;
                default:
                    throw new BizException("审核人类型异常");
            }
        }
    }


    /**
     * 处理xml流程条件
     */
    private void handleSequenceFlowElement(ActivitiForm activitiForm, Process process, List<ConditionExpression> conditionExpressions) {
        // deptMap
        List<Department> deptList = departmentService.list();
        Map<String, Department> deptMap = ListHelper.toMap(Department::getId, deptList);
        // conditionMetaMap
        List<ConditionMeta> conditionMetaList = JSON.parseArray(activitiForm.getConditionMetaContent(), ConditionMeta.class);
        Map<String, ConditionMeta> conditionMetaMap = ListHelper.toMap(ConditionMeta::getField, conditionMetaList);
        //   conditionExpressionsMap
        Map<String, ConditionExpression> conditionExpressionsMap = ListHelper.toMap(ConditionExpression::getElementId, conditionExpressions);
        for (String elementId : conditionExpressionsMap.keySet()) {
            FlowElement flowElement = process.getFlowElement(elementId);
            if (flowElement == null) {
                throw new BizException("conditionExpression 没有找到对应的 sequenceFlow");
            }
            ConditionExpression conditionExpression = conditionExpressionsMap.get(elementId);
            // [conditionField] [conditionOperator] [conditionValue] 例子 amt > 10
            String conditionField = conditionExpression.getConditionField();
            String conditionOperator = conditionExpression.getConditionOperator();
            String conditionValue = conditionExpression.getConditionValue();
            String conditionHasTax = conditionExpression.getHasTax();
            String isInMyCompany = conditionExpression.getIsInMyCompany();
            String conditionEntryType = conditionExpression.getEntryType();
            String conditionPayFundType = conditionExpression.getPayFundType();

            /** 自定义表单值*/
            String customFormId = conditionExpression.getCustomFormId();
            /** 自动义表单数据*/
            String customFormField = conditionExpression.getCustomFormField();
            String customFormFieldName = conditionExpression.getCustomFormFieldName();
            String customFormIdType = conditionExpression.getCustomFormIdType();


            // 销售方式多选
            List<String> conditionSaleTypeList= conditionExpression.getSaleTypeList();
            // 专门处理申请人多选
            List<String> conditionPersonIdList = conditionExpression.getConditionPersonIdList();
            // 专门处理业务类型多选
            List<String> conditionBusinessTypeList = conditionExpression.getBusinessTypeList();
            // 专门处理厂区多选
            List<String> conditionCompanyIdList = conditionExpression.getCompanyIdList();
            // 专门处理部门多选
            List<String> conditionDeptIdList = conditionExpression.getConditionDeptIdList();
            // 专门处理生产线多选
            List<String> conditionLineIdList = conditionExpression.getConditionLineIdList();
            // 专门处理碰伤类型多选
            List<String> conditionBruiseTypeList = conditionExpression.getBruiseTypeList();
            // 专门处理停工原因多选
            List<String> sdtList = conditionExpression.getSdtList();
            // 专门处理费用报销
            List<String> reimbursementTypeList = conditionExpression.getReimbursementTypeList();
            // 镀锌品类
            List<String> category = conditionExpression.getCategory();
            // 款项转款类型
            List<String> transferTypeList = conditionExpression.getTransferTypeList();
            // 工伤报销类型
            List<String> workInjuryTypeList = conditionExpression.getWorkInjuryTypeList();
            // 款项类型
            List<String> fundTypeList = conditionExpression.getFundTypeList();
            ConditionType conditionType = ConditionType.getEnum(conditionExpression.getConditionType());
            // 验证
            ConditionMeta conditionMeta = conditionMetaMap.get(conditionField);
            if (conditionMeta == null) {
                throw new BizException("提交的条件和表单不匹配");
            }
            if (!conditionMeta.getType().equals(conditionType.getType())) {
                throw new BizException("提交的条件类型异常");
            }
            SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
            switch (conditionType) {
                case OP:
                    if (conditionOperator.contains("lt")) {
                        conditionOperator = "<";
                    } else if (conditionOperator.contains("le")) {
                        conditionOperator = "<=";
                    } else if (conditionOperator.contains("eq")) {
                        conditionOperator = "==";
                    } else if (conditionOperator.contains("ge")) {
                        conditionOperator = ">=";
                    } else if (conditionOperator.contains("gt")) {
                        conditionOperator = ">";
                    } else if (conditionOperator.contains("ne")) {
                        conditionOperator = "!=";
                    } else {
                        throw new BizException("提交的运算符异常");
                    }
                    if (StringUtils.isEmpty(conditionValue)) {
                        throw new BizException("提交的运算符操作数异常");
                    }
                    boolean isMatch = Pattern.matches(PatternConstants.DECIMAL, conditionValue);
                    if (!isMatch) {
                        throw new BizException("提交的运算符操作数异常");
                    }
                    sequenceFlow.setConditionExpression("${" + conditionField + conditionOperator + conditionValue + "}");
                    break;
                case DE:
                    List<String> deptElList = new ArrayList<>();
                    for (String deptId : conditionDeptIdList) {
                        if (!deptMap.containsKey(deptId)) {
                            throw new BizException("提交的部门条件异常");
                        }
                        deptElList.add(conditionField + "==" + deptId);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", deptElList) + "}");
                    break;
                case LI:
                    List<String> lineElList = new ArrayList<>();
                    for (String lineId : conditionLineIdList) {
                        lineElList.add(conditionField + "==" + lineId);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", lineElList) + "}");
                    break;
                case SDT:
                    List<String> sdtElList = new ArrayList<>();
                    for (String sdt : sdtList) {
                        sdtElList.add(conditionField + "==" + sdt);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", sdtElList) + "}");
                    break;
                case FYBX:
                    List<String> reimbursementTypeElList = new ArrayList<>();
                    for (String type : reimbursementTypeList) {
                        reimbursementTypeElList.add(conditionField + "==" + type);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", reimbursementTypeElList) + "}");
                    break;
                case BOOL0:
                    conditionField = conditionField.replaceAll("BOOL0", "");
                    conditionField = conditionField.replaceAll("BOOL1", "");
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + CommonConst.FALSE + "}");
                    break;
                case BOOL1:
                    conditionField = conditionField.replaceAll("BOOL0", "");
                    conditionField = conditionField.replaceAll("BOOL1", "");
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + CommonConst.TRUE + "}");
                    break;
                case HT:
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + conditionHasTax+ "}");
                    break;
                case FUNDTYPE:
                    // 条件不能使用单个字母，推荐使用数字
                    int fundType = "A".equals(conditionPayFundType) ? 1 : ("B".equals(conditionPayFundType) ? 2 : 3);
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + fundType+ "}");
                    /*List<String> fundTypeElList = new ArrayList<>();
                    for (String fundType : fundTypeList) {
                        fundTypeElList.add(conditionField + "==" + fundType);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", fundTypeElList) + "}");*/
                    break;
                case CQ:
                    List<String> companyElList = new ArrayList<>();
                    for (String companyId : conditionCompanyIdList) {
                        companyElList.add(conditionField + "==" + companyId);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||", companyElList) + "}");
                    break;
                case PERSON:
                    List<String> personElList = new ArrayList<>();
                    for (String personId : conditionPersonIdList) {
                        personElList.add(conditionField + "==" + personId);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",personElList) + "}");
                    break;
                case LRFPLX:
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + conditionEntryType+ "}");
                    break;
                case SHFS:
                    List<String> saleTypeList = new ArrayList<>();
                    for (String saleType : conditionSaleTypeList) {
                        saleTypeList.add(conditionField + "==" + saleType);
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",saleTypeList) + "}");
                    break;
                case YWLX:
                    List<String> businessTypeList = new ArrayList<>();
                    for (String businessType : conditionBusinessTypeList) {
                        businessTypeList.add(conditionField + "==" + "'" + businessType + "'"); // 字母
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",businessTypeList) + "}");
                    break;
                case PSLX:
                    List<String> bruiseTypeList = new ArrayList<>();
                    for (String bruiseType : conditionBruiseTypeList) {
                        bruiseTypeList.add(conditionField + "==" + "'" + bruiseType + "'"); // 字母
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",bruiseTypeList) + "}");
                    break;
                case CATEGORY:
                    List<String> _category = new ArrayList<>();
                    for (String c : category) {
                        _category.add(conditionField + "==" + "'" + c + "'"); // 字母
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",_category) + "}");
                    break;
                case GSBXLX:
                    List<String> workInjuryType = new ArrayList<>();
                    for (String c : workInjuryTypeList) {
                        workInjuryType.add(conditionField + "==" + "'" + c + "'"); // 字母
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",workInjuryType) + "}");
                    break;
                case ZKLX:
                    List<String> transferType = new ArrayList<>();
                    for (String c : transferTypeList) {
                        transferType.add(conditionField + "==" + "'" + c + "'"); // 字母
                    }
                    sequenceFlow.setConditionExpression("${" + String.join("||",transferType) + "}");
                    break;
                case ISINMYCOMPANY:
                    sequenceFlow.setConditionExpression("${" + conditionField + "==" + isInMyCompany+ "}");
                    break;
                case FORM:
                    ConditionType customFormItemType = ConditionType.getEnum(customFormIdType);
                    switch (customFormItemType){
                        case DE:
                            List<String> customFormDeptElList = new ArrayList<>();
                            for (String deptId : conditionDeptIdList) {
                                if (!deptMap.containsKey(deptId)) {
                                    throw new BizException("提交的部门条件异常");
                                }
                                customFormDeptElList.add(customFormField + "==" + deptId);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||", customFormDeptElList) + "}");
                            break;
                        case PERSON:
                            List<String> customFormPersonElList = new ArrayList<>();
                            for (String personId : conditionPersonIdList) {
                                customFormPersonElList.add(customFormField + "==" + personId);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",customFormPersonElList) + "}");
                            break;
                        case YWLX:
                            List<String> customFormBusinessTypeList = new ArrayList<>();
                            for (String businessType : conditionBusinessTypeList) {
                                customFormBusinessTypeList.add(customFormField + "==" + "'" + businessType + "'"); // 字母
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",customFormBusinessTypeList) + "}");
                            break;
                        case LI:
                            List<String> customFormLineElList = new ArrayList<>();
                            for (String lineId : conditionLineIdList) {
                                customFormLineElList.add(customFormField + "==" + lineId);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||", customFormLineElList) + "}");
                            break;
                        case GSBXLX:
                            List<String> workInjuryTypeElList = new ArrayList<>();
                            for (String c : workInjuryTypeList) {
                                workInjuryTypeElList.add(customFormField + "==" + "'" + c + "'"); // 字母
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",workInjuryTypeElList) + "}");
                            break;
                        case ZKLX:
                            List<String> transferTypeElList = new ArrayList<>();
                            for (String c : transferTypeList) {
                                transferTypeElList.add(customFormField + "==" + "'" + c + "'"); // 字母
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",transferTypeElList) + "}");
                            break;
                        case CATEGORY:
                            List<String> _categoryElList = new ArrayList<>();
                            for (String c : category) {
                                _categoryElList.add(customFormField + "==" + "'" + c + "'"); // 字母
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",_categoryElList) + "}");
                            break;
                        case PSLX:
                            List<String> bruiseTypeElList = new ArrayList<>();
                            for (String bruiseType : conditionBruiseTypeList) {
                                bruiseTypeElList.add(customFormField + "==" + "'" + bruiseType + "'"); // 字母
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",bruiseTypeElList) + "}");
                            break;
                        case SHFS:
                            List<String> saleTypeElList = new ArrayList<>();
                            for (String saleType : conditionSaleTypeList) {
                                saleTypeElList.add(customFormField + "==" + saleType);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||",saleTypeElList) + "}");
                            break;
                        case LRFPLX:
                            sequenceFlow.setConditionExpression("${" + customFormField + "==" + conditionEntryType+ "}");
                            break;
                        case CQ:
                            List<String> companyIdElList = new ArrayList<>();
                            for (String companyId : conditionCompanyIdList) {
                                companyIdElList.add(customFormField + "==" + companyId);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||", companyIdElList) + "}");
                            break;
                        case SDT:
                            List<String> sdtCustomFormElList = new ArrayList<>();
                            for (String sdt : sdtList) {
                                sdtCustomFormElList.add(customFormField + "==" + sdt);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||", sdtCustomFormElList) + "}");
                            break;
                        case FYBX:
                            List<String> customFormElList = new ArrayList<>();
                            for (String type : reimbursementTypeList) {
                                customFormElList.add(customFormField + "==" + type);
                            }
                            sequenceFlow.setConditionExpression("${" + String.join("||", customFormElList) + "}");
                            break;
                        default:
                            throw new BizException("流程提交的条件数据异常");
                    }
                    break;
                default:
                    throw new BizException("提交的条件数据异常");
            }
        }
    }

    /**
     * 清除xml上一些奇怪的东西
     */
    private void cleanAttributes(Process process) {
        List<UserTask> userTaskList = new ArrayList<>();
        List<SequenceFlow> sequenceFlowList = new ArrayList<>();
        Collection<FlowElement> flowElements = process.getFlowElements();
        for (FlowElement element : flowElements) {
            if (element instanceof UserTask) {
                userTaskList.add((UserTask) element);
            } else if (element instanceof SequenceFlow) {
                sequenceFlowList.add((SequenceFlow) element);
            }
            logger.info("==========>element name : " + element.getName());
        }
        for (UserTask userTask : userTaskList) {
            userTask.setAttributes(new HashMap<>());
        }
        for (SequenceFlow sequenceFlow : sequenceFlowList) {
            sequenceFlow.setAttributes(new HashMap<>());
        }
    }
}
